#!/bin/bash
#
# Written by Ishimoto Shinobu
#
# Also thanks Void linux!
#

msg() { printf "\033[1;34m::\033[0m %s\n" "$@"; }
die() { printf "\033[1;31m::\033[0m %s\n" "$@"; exit 1; }

check_updates() {
	local distfiles i url

	if [ "$TORSOCKS" = "true" ]; then
		MYCURL="torsocks curl"
	else
		MYCURL="curl"
	fi

	mypkg="$1"

	if [ ! -f "$mypkg/KagamiBuild" ]; then
		return 0
	fi

	source "$mypkg/KagamiBuild"

	myhomepage="$(grep "^# URL[[:blank:]]*:" $mypkg/KagamiBuild | sed 's/^# URL[[:blank:]]*:[[:blank:]]*//' | tr ' ' '\n' | awk '!a[$0]++')"
	homepage="$myhomepage"
	for i in ${source[@]}; do
		if echo $i | grep -q '::archive='; then
			url="$(echo $i | sed -e 's/::archive=/ /g' | awk '{print $1}')"
		else
			url="$i"
		fi

		if [ -n "$distfiles" ]; then
			distfiles="$distfiles $url"
		else
			distfiles="$url"
		fi
	done

	local i p url sfname lpname bbname githubname rx found_version consider
	local update_override=$mypkg/update
	local original_name=$name
	local urlpfx urlsfx

	if [ -r $update_override ]; then
		. $update_override
	fi

	if ! type curl >/dev/null 2>&1; then
		die "cannot find \`curl' executable!"
	fi

	export LC_ALL=C

	if [ -z "$site" ]; then
		case "$distfiles" in
			*download.gnome.org*) ;;
			*) printf '%s\n' "$homepage" ;;
		esac
		for i in $distfiles; do
			printf '%s\n' "${i%/*}/"
		done
	else
		printf '%s\n' "$site"
	fi |
	while IFS= read -r url; do
		printf '%s\n' "$url"
		if [ "$single_directory" ]; then
			continue
		fi
		rx=
		urlpfx="${url}"
		urlsfx=
		dirpfx=
		case "$url" in
			  *sourceforge.net/sourceforge*|\
			  *code.google.com*|*googlecode*|\
			  *launchpad.net*|\
			  *cpan.*|\
			  *pythonhosted.org*|\
			  *github.com*|\
			  *//gitlab.*|\
			  *bitbucket.org*|\
			  *ftp.gnome.org*|\
			  *kernel.org/pub/linux/kernel/*|\
			  *cran.r-project.org/src/contrib*|\
			  *rubygems.org*)
				continue
				;;
			*)
				vdpfx=${vdprefix:-"|v|\\Q$name\\E"}
				vdsfx=${vdsuffix:-"|\\.x"}
				match=$(grep -Po "^[^/]+//[^/]+(/.+)?/($vdpfx)(?=[-_.0-9]*[0-9](?<!\\Q$name\\E)($vdsfx)/)" <<< "$url")
				if [ "$?" = 0 ]; then
					urlpfx="${match%/*}/"
					dirpfx="${match##*/}"
					urlsfx="${url#$urlpfx}"
					urlsfx="${urlsfx#*/}"
					rx="href=[\"']?(\\Q$urlpfx\\E)?\\.?/?\\K\\Q$dirpfx\\E[-_.0-9]*[0-9]($vdsfx)[\"'/]"
				fi
				;;
		esac
		if [ "$rx" ]; then
			skipdirs=
			$MYCURL --max-time 10 -Lsk "$urlpfx" |
				grep -Po -i "$rx" |
				# sort -V places 1.1/ before 1/, but 1A/ before 1.1A/
				sed -e 's:$:A:' -e 's:/A$:A/:' | sort -Vru | sed -e 's:A/$:/A:' -e 's:A$::' |
				while IFS= read -r newver; do
					newurl="${urlpfx}${newver}${urlsfx}"
					if [ "$newurl" = "$url" ]; then
						skipdirs=yes
					fi
					if [ -z "$skipdirs" ]; then
						printf '%s\n' "$newurl"
					fi
				done
		fi
	done |
	while IFS= read -r url; do
		rx=
		if [ -z "$site" ]; then
			case "$url" in
			*sourceforge.net/sourceforge*)
				sfname="$(printf %s "$url" | cut -d/ -f5)"
				url="https://sourceforge.net/projects/$sfname/rss?limit=200";;
			*code.google.com*|*googlecode*)
				url="http://code.google.com/p/$name/downloads/list";;
			*launchpad.net*)
				lpname="$(printf %s "$url" | cut -d/ -f4)"
				url="https://launchpad.net/$lpname/+download";;
			*cpan.*)
				name=${name#perl-};;
			*pythonhosted.org*)
				name=${name#python-}
				name=${name#python3-}
				url="https://pypi.org/simple/$name";;
			*github.com*)
				githubname="$(printf %s "$url" | cut -d/ -f4,5)"
				url="https://github.com/$githubname/tags"
				rx='/archive/refs/tags/(v?|\Q'"$name"'\E-)?\K[\d\.]+(?=\.tar\.gz")';;
			*//gitlab.*)
				gitlaburl="$(printf %s "$url" | cut -d/ -f1-5)"
				url="$gitlaburl/tags"
				rx='/archive/[^/]+/\Q'"$name"'\E-v?\K[\d\.]+(?=\.tar\.gz")';;
			*bitbucket.org*)
				bbname="$(printf %s "$url" | cut -d/ -f4,5)"
				url="https://bitbucket.org/$bbname/downloads"
				rx='/(get|downloads)/(v?|\Q'"$name"'\E-)?\K[\d\.]+(?=\.tar)';;
			*download.gnome.org*)
				: ${pattern="\Q$name\E-\K(0|[13]\.[0-9]*[02468]|[4-9][0-9]+)\.[0-9.]*[0-9](?=)"}
				url="https://download.gnome.org/sources/$name/cache.json";;
			*kernel.org/pub/linux/kernel/*)
				rx=linux-'\K'${version%.*}'[\d.]+(?=\.tar\.xz)';;
			*cran.r-project.org/src/contrib*)
				rx='\b\Q'"${name#R-cran-}"'\E_\K\d+(\.\d+)*(-\d+)?(?=\.tar)';;
			*rubygems.org*)
				url="https://rubygems.org/gems/${name#ruby-}"
				rx='href="/gems/'${name#ruby-}'/versions/\K[\d\.]*(?=")' ;;
			*crates.io*)
				url="https://crates.io/api/v1/crates/${name#rust-}"
				rx='/crates/'${name#rust-}'/\K[0-9.]*(?=/download)' ;;
			esac
		fi

		rx=${pattern:-$rx}
		rx=${rx:-'(?<!-)\b\Q'"$name"'\E[-_]?((src|source)[-_])?\K([^-/_\s]*?\d[^-/_\s]*?)(?=(?:[-_.](?:src|source|orig))?\.(?:[jt]ar|shar|t[bglx]z|tbz2|zip))\b'}
		$MYCURL -H 'Accept: text/html,application/xhtml+xml,application/xml,text/plain,application/rss+xml' --max-time 10 -Lsk "$url" |
			grep -P -o -i "$rx"
	done |
	tr _ . |
	sort -Vu |
	while IFS= read -r found_version; do
		consider=true
		p="$ignore "
		while [ -n "$p" ]; do
			i=${p%% *}
			p=${p#* }
			case "$found_version" in
			$i)
				consider=false
			esac
		done
		if $consider; then
			vercmp "$original_name-${version}_1" "$original_name-$(printf %s "$found_version" | tr - .)_1"
			if [ $? = 255 ]; then
				if [ "$AUTOBUMP" = "yes" ]; then
					msg "Auto-updating ${original_name} to $found_version"
					local oldver oldrel
					found_version="$(printf %s "$found_version" | tr - +)"
					oldver="$(grep ^version $mypkg/KagamiBuild | sed -e 's,version=,,g' )"
					oldrel="$(grep ^release $mypkg/KagamiBuild | sed -e 's,release=,,g' )"
					sed -i "s,version=${oldver},version=${found_version},g" "$mypkg/KagamiBuild"
					sed -i "s,release=${oldrel},release=1,g" "$mypkg/KagamiBuild"
					if [ "$AUTOCOMMIT" = "yes" ]; then
						git add $mypkg
						git commit -S -m "bump ${original_name} to ${found_version}"
					fi
				else
					msg "Update ${original_name} to ${found_version}"
				fi
			fi
		fi
	done
}

AUTOBUMP="no"

while getopts ac options; do
	case $options in
		a)
			AUTOBUMP="yes"
			;;
		c)
			AUTOCOMMIT="yes"
			;;
	esac
done
shift $((OPTIND - 1))

for a in "$@"; do
	check_updates $a
done

exit 0
